package logica.interfaces;

import java.util.List;

import logica.exceptions.DoesNotContainException;
import logica.exceptions.InvalidActionException;
import logica.exceptions.InvalidDataException;
import logica.exceptions.RequiredDataException;

/**
 * Interface que encapsula o comportamento de um produto do leilao virtual.
 *
 *
 */
public interface ProductIF {

	// Produto Simples
	/**
	 *  Valor fixo para um produto simples.
	 */
	public static final String SIMPLE = "SIMPLE";

	// Agrupamento de produtos.
	/**
	 * Valor fixo para um grupo de produto.
	 */
	public static final String GROUP = "GROUP";

	/**
	 * Valor fixo para produto disponivel.
	 */
	public static final boolean DISPONIVEL = true;

	/**
	 * valor fixo para produto nao disponivel.
	 */
	public static final boolean NAO_DISPONIVEL = false;

	/**
	 * Retorna o id do produto.
	 *
	 * @return O id do produto.
	 */
	public String getId();

	/**
	 * Retorna o login dono do produto.
	 *
	 * @return o login dono do produto.
	 */
	public String getOwner();

	/**
	 * Retorna o nome do produto.
	 *
	 * @return o nome do produto.
	 */
	public String getName();

	/**
	 * Atualiza o nome do produto.
	 *
	 * @param name
	 *            o novo nome.
	 *
	 * @throws RequiredDataException
	 *             Se o nome for nulo ou vazio.
	 */
	public void setName(String name) throws RequiredDataException;

	/**
	 * Retorna a descricao do produto.
	 *
	 * @return a descricao do produto.
	 */
	public String getDescription();

	/**
	 * Atualiza a descricao do produto.
	 *
	 * @param description
	 *            a nova descricao.
	 * @throws RequiredDataException
	 *             Se a descricao for nula ou vazia.
	 */
	public void setDescription(String description) throws RequiredDataException;

	/**
	 * Retorna o identificador da categoria do produto.
	 *
	 * @return o identificador da categoria do produto.
	 */
	public String getCategoryId();

	/**
	 * Atualiza o identificador de categoria. Muda o produto de categoria.
	 *
	 * @param categoryId
	 *            identificador da nova categoria.
	 * @throws InvalidDataException
	 *             Se a nova categoria nao existir.
	 */
	public void setCategoryId(String categoryId) throws InvalidDataException;

	/**
	 * Retorna o status do produto.
	 *
	 * @return o status do produto.
	 */
	public String getStatus();

	/**
	 * Atualiza o status do produto.
	 *
	 * @param status
	 *            o novo status.
	 * @throws RequiredDataException
	 *             Se o status for null ou vazio.
	 */
	public void setStatus(String status) throws RequiredDataException;

	/**
	 * Retorna a quantidade de produtos.
	 *
	 * @return a quantidade de produtos.
	 */
	public int getQuantity();

	/**
	 * Atualiza a quantidade de produtos.
	 *
	 * @param quantity
	 *            nova quantidade.
	 * @throws InvalidDataException
	 *             Se a quantidade for negativa.
	 */
	public void setQuantity(int quantity) throws InvalidDataException;

	/**
	 * Retorna a quantidade de interessados no produto.
	 *
	 * @return a quantidade de interessados no produto.
	 */
	public int getQuantityInteress();

	/**
	 * Atualiza a quantidade de interessados no produto.
	 *
	 * @param quantityInteress
	 *            a nova quantidade de interessados.
	 * @throws InvalidDataException
	 *             se a quantidade de interessados for menor que zero.
	 */
	public void setQuantityInteress(int quantityInteress)
			throws InvalidDataException;

	/**
	 * Retorna o preco inicial do produto.
	 *
	 * @return o preco inicial do produto.
	 */
	public double getInicialPrice();

	/**
	 * Atualiza o preco inicial do preco.
	 *
	 * @param inicialPrice
	 *            o novo preco inicial.
	 * @throws InvalidDataException
	 *             Se o preco inicial for menor que zero.
	 */
	public void setInicialPrice(double inicialPrice)
			throws InvalidDataException;

	/**
	 * Retorna o tipo do produto.
	 *
	 * @return o tipo do produto.
	 */
	public String getType();

	/**
	 * Atualiza o tipo do produto.
	 *
	 * @param type
	 *            o novo tipo.
	 * @throws RequiredDataException
	 *             Se o novo tipo for nulo ou vazio.
	 */
	public void setType(String type) throws RequiredDataException;

	/**
	 * Adiciona um usuario a lista de interessados no produto.
	 *
	 * @param UserSession
	 *            login o usuario interessado.
	 */
	public void addInterest(String login);

	/**
	 * Retorna a lista de interessados no produto.
	 *
	 * @return Retorna a lista de interessados no produto.
	 */
	public List<String> getInterested();

	/**
	 * Adiciona um produto ao produto atual.
	 *
	 * @param ProductIF
	 *            newItem o produto a ser adicionado.
	 * @throws InvalidActionException
	 *             Se o produto atual for simples.
	 * @throws InvalidDataException
	 */
	public void addItem(ProductIF idItem) throws InvalidActionException,
			InvalidDataException;

	/**
	 * Remove um item do produto atual.
	 *
	 * @param ProductIF
	 *            item o item a ser removido.
	 * @return true se o processo for bem sucessido.
	 * @throws InvalidActionException
	 *             Se o produto atual for simples.
	 * @throws InvalidDataException
	 * @throws ProductDoesNotContainException
	 */
	public boolean removeItem(ProductIF idItem) throws InvalidActionException,
			DoesNotContainException, InvalidDataException;

	/**
	 * Retorna a quantidade de usuarios interessados no produto.
	 *
	 * @return a quantidade de usuarios interessados no produto.
	 */
	public int getInterestedQuantity();

	/**
	 * Atualiza o nome do dono do produto.
	 *
	 * @param owner
	 *            O login do novo dono.
	 */
	public void setOwner(String owner) throws RequiredDataException;

	/**
	 * Adiciona um listener de leiloes ao produto.
	 *
	 * @param a
	 *            Evento de anuncio de leilao.
	 */
	public void addListener(AuctionListener a);

	/**
	 * Joga o evento de anuncio de leialao aos listeners.
	 *
	 * @param aucOwner
	 *            o dono do leilao.
	 * @param aucDescription
	 *            A descricao do leilao.
	 * @param date
	 *            A data dio leilao.
	 * @param beginTime
	 *            O tempo de inicio do leilao.
	 * @param endTime
	 *            O tempo de fim do leilao.
	 */
	public void initEvent(String aucOwner, String aucDescription, String date,
			String beginTime, String endTime);
}
